<template>
  <div>
    <el-form ref="myform" :model="formItem" :rules="rules" label-width="80px" size="mini">
      <el-form-item label="班次名称" prop="name">
        <el-input v-model="formItem.name" />
      </el-form-item>
      <el-form-item label="班次项" prop="items">
        <el-button size="mini" icon="el-icon-plus" @click="addItem">添加</el-button>
      </el-form-item>
      <el-row v-for="(item,index) in formItem.items" :key="index" :gutter="40">
        <el-col :span="6">
          <el-form-item label="项名称" :prop="'items.' + index + '.name'" :rules="rules.name">
            <el-input v-model="item.name" />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="天数" :prop="'items.' + index + '.cycle'" :rules="rules.cycle">
            <el-input-number v-model="item.cycle" :min="1" :max="15" label="天数" />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="开始时间" :prop="'items.' + index + '.startTime'" :rules="rules.startTime">
            <el-time-select v-model="item.startTime" :picker-options="pickerOptions" placeholder="开始时间" />
          </el-form-item>
        </el-col>
        <el-col :span="5">
          <el-form-item label="结束时间" :prop="'items.' + index + '.endTime'" :rules="rules.endTime">
            <el-time-select v-model="item.endTime" :picker-options="pickerOptions" placeholder="结束时间" />
          </el-form-item>
        </el-col>
        <el-col :span="3">
          <el-button type="danger" icon="el-icon-delete" circle @click="remove(index)" />
        </el-col>
      </el-row>
      <el-row :gutter="40" />
    </el-form>
  </div>
</template>

<script>
import { detail, create, update } from '@neu/dcom-ui/api/classes'

// 定义一个表单原始项
const formItem = {
  name: '',
  items: []
}
export default {
  name: 'ClassesForm',
  props: {
    // 根据id可判断是新建还是更新
    id: {
      required: false,
      type: Number,
      default: -1
    }
  },
  data() {
    return {
      // 编辑的表单内容
      formItem: {
        ...formItem
      },
      pickerOptions: {
        start: '00:00',
        step: '00:30',
        end: '24:00'
      },
      // 表单验证规则
      rules: {
        name: [{ required: true, message: '班次不能为空', trigger: 'blur' }],
        cycle: [{ required: true, message: '天数不能为空', trigger: 'blur' }],
        startTime: [{ required: true, message: '开始时间时间不能为空', trigger: 'blur' }],
        endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }],
        items: [{
          required: true,
          message: '至少含有一个时间段',
          trigger: 'blur'
        },
        {
          validator: function(rule, value, callback) {
            if (value.length < 1) {
              callback(new Error('至少含有一个时间段'))
            } else {
              callback()
            }
          },
          trigger: 'blur'
        }]
      }
    }
  },
  watch: {
    // 监控id的变化，初始化表单数据
    id: function() {
      this.fetch()
    }
  },
  created() {
    this.fetch()
  },
  methods: {
    // 初始化表单数据
    fetch() {
      this.reset()
      if (this.id !== -1) {
        detail(this.id).then(response => {
          this.formItem = {
            ...response.data
          }
        })
      } else {
        this.formItem = {
          ...formItem
        }
      }
    },
    // 保存操作，返回promise，后续处理交由调用者处理
    save() {
      const updated = this.id !== -1
      return new Promise(resolve => {
        this.$refs.myform.validate((valid) => {
          if (valid) {
            this.formItem.items.forEach(s => {
              if (!this.comparePeriod(s.startTime, s.endTime)) {
                this.$message({
                  showClose: true,
                  message: s.name + '班次的开始时间必须小于结束时间',
                  type: 'error'
                })
                resolve(false)
              }
            })
            const setTestArr = new Set(this.formItem.items.map(e => e.cycle))
            // 校验周期连续性
            for (let i = 1; i <= setTestArr.size; i++) {
              if (i === 1 && setTestArr.has(i) === false) {
                this.$message({
                  showClose: true,
                  message: '天数必须从第一天开始',
                  type: 'error'
                })
                resolve(false)
                break
              }
              if (setTestArr.has(i) === false) {
                this.$message({
                  showClose: true,
                  message: '天数必须连续',
                  type: 'error'
                })
                resolve(false)
                break
              }
            }

            // 校验时间重复性
            setTestArr.forEach(m => {
              var startTime = []
              var endTime = []
              this.formItem.items.filter(k => k.cycle === m).forEach(s => {
                startTime.push(s.startTime)
                endTime.push(s.endTime)
              })
              if (!this.compareDate(startTime, endTime)) {
                this.$message({
                  showClose: true,
                  message: '同一周期内时间段不能重复',
                  type: 'error'
                })
                resolve(false)
              }
            })

            if (updated) {
              resolve(update(this.id, this.formItem))
            } else {
              resolve(create(this.formItem))
            }
          } else {
            resolve(false)
          }
        })
      })
    },
    reset() {
      // this.$refs.myform.resetFields()
      this.formItem.items = []
      formItem.items = []
    },
    remove(index) {
      this.formItem.items.splice(index, 1)
    },
    addItem() {
      this.formItem.items.push({ name: '', startTime: null, endTime: null, cycle: 1 })
    },
    // 比较时间段重复
    compareDate(begin, over) {
      begin = begin.sort()
      over = over.sort()
      for (var i = 1; i < begin.length; i++) {
        if (begin[i] < over[i - 1]) {
          return false
        }
      }
      return true
    },
    // 比较两个时间段的大小
    comparePeriod(begin, over) {
      if (begin.substr(0, 2) === over.substr(0, 2)) {
        return Number(begin.substr(3, 4)) < Number(over.substr(3, 4))
      } else {
        return Number(begin.substr(0, 2)) < Number(over.substr(0, 2))
      }
    }
  }
}
</script>
